/**
 * 认证相关工具函数
 */

import { StorageKeys, type UserInfo } from '@/types'

/**
 * 本地存储工具
 */
export const storage = {
  // 获取 localStorage 项
  get: (key: string): string | null => {
    try {
      return localStorage.getItem(key)
    } catch (error) {
      console.warn('Failed to get localStorage item:', error)
      return null
    }
  },

  // 设置 localStorage 项
  set: (key: string, value: string): void => {
    try {
      localStorage.setItem(key, value)
    } catch (error) {
      console.warn('Failed to set localStorage item:', error)
    }
  },

  // 删除 localStorage 项
  remove: (key: string): void => {
    try {
      localStorage.removeItem(key)
    } catch (error) {
      console.warn('Failed to remove localStorage item:', error)
    }
  },

  // 清空 localStorage
  clear: (): void => {
    try {
      localStorage.clear()
    } catch (error) {
      console.warn('Failed to clear localStorage:', error)
    }
  }
}

/**
 * Token 相关操作
 */
export const tokenUtils = {
  // 获取访问令牌
  getAccessToken: (): string | null => {
    return storage.get(StorageKeys.ACCESS_TOKEN)
  },

  // 设置访问令牌
  setAccessToken: (token: string): void => {
    storage.set(StorageKeys.ACCESS_TOKEN, token)
  },

  // 获取刷新令牌
  getRefreshToken: (): string | null => {
    return storage.get(StorageKeys.REFRESH_TOKEN)
  },

  // 设置刷新令牌
  setRefreshToken: (token: string): void => {
    storage.set(StorageKeys.REFRESH_TOKEN, token)
  },

  // 获取令牌类型
  getTokenType: (): string => {
    return storage.get(StorageKeys.TOKEN_TYPE) || 'Bearer'
  },

  // 设置令牌类型
  setTokenType: (type: string): void => {
    storage.set(StorageKeys.TOKEN_TYPE, type)
  },

  // 获取过期时间
  getExpiresAt: (): number | null => {
    const expiresAt = storage.get(StorageKeys.EXPIRES_AT)
    return expiresAt ? parseInt(expiresAt, 10) : null
  },

  // 设置过期时间
  setExpiresAt: (timestamp: number): void => {
    storage.set(StorageKeys.EXPIRES_AT, timestamp.toString())
  },

  // 检查令牌是否过期
  isTokenExpired: (): boolean => {
    const expiresAt = tokenUtils.getExpiresAt()
    if (!expiresAt) return true
    
    // 提前 5 分钟判断过期，避免临界情况
    const fiveMinutes = 5 * 60 * 1000
    return Date.now() >= (expiresAt - fiveMinutes)
  },

  // 清除所有令牌
  clearTokens: (): void => {
    storage.remove(StorageKeys.ACCESS_TOKEN)
    storage.remove(StorageKeys.REFRESH_TOKEN)
    storage.remove(StorageKeys.TOKEN_TYPE)
    storage.remove(StorageKeys.EXPIRES_AT)
  }
}

/**
 * 用户信息相关操作
 */
export const userUtils = {
  // 获取用户信息
  getUserInfo: (): UserInfo | null => {
    try {
      const userInfo = storage.get(StorageKeys.USER_INFO)
      return userInfo ? JSON.parse(userInfo) : null
    } catch (error) {
      console.warn('Failed to parse user info:', error)
      return null
    }
  },

  // 设置用户信息
  setUserInfo: (userInfo: UserInfo): void => {
    try {
      storage.set(StorageKeys.USER_INFO, JSON.stringify(userInfo))
    } catch (error) {
      console.warn('Failed to set user info:', error)
    }
  },

  // 清除用户信息
  clearUserInfo: (): void => {
    storage.remove(StorageKeys.USER_INFO)
  }
}

/**
 * 记住我功能
 */
export const rememberMe = {
  // 获取记住我状态
  getRememberMe: (): boolean => {
    return storage.get(StorageKeys.REMEMBER_ME) === 'true'
  },

  // 设置记住我状态
  setRememberMe: (remember: boolean): void => {
    storage.set(StorageKeys.REMEMBER_ME, remember.toString())
  },

  // 清除记住我状态
  clearRememberMe: (): void => {
    storage.remove(StorageKeys.REMEMBER_ME)
  }
}

/**
 * 表单验证工具
 */
export const validators = {
  // 用户名验证
  username: (value: string): boolean => {
    return /^[a-zA-Z0-9_]{3,20}$/.test(value)
  },

  // 邮箱验证
  email: (value: string): boolean => {
    return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)
  },

  // 手机号验证（中国大陆）
  phone: (value: string): boolean => {
    return /^1[3-9]\d{9}$/.test(value)
  },

  // 密码强度验证
  password: (value: string): boolean => {
    // 至少8位，包含字母和数字
    return /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/.test(value)
  },

  // 验证码验证
  verifyCode: (value: string): boolean => {
    return /^\d{6}$/.test(value)
  },

  // 账号验证（用户名、邮箱或手机号）
  account: (value: string): boolean => {
    return validators.username(value) || validators.email(value) || validators.phone(value)
  }
}

/**
 * 密码强度检测
 */
export const getPasswordStrength = (password: string): { level: number; text: string; color: string } => {
  let level = 0
  const checks = [
    password.length >= 8,
    /[a-z]/.test(password),
    /[A-Z]/.test(password),
    /\d/.test(password),
    /[!@#$%^&*(),.?":{}|<>]/.test(password)
  ]
  
  level = checks.filter(Boolean).length
  
  if (level <= 2) {
    return { level, text: '弱', color: '#f56565' }
  } else if (level <= 3) {
    return { level, text: '中', color: '#ed8936' }
  } else if (level <= 4) {
    return { level, text: '强', color: '#38a169' }
  } else {
    return { level, text: '很强', color: '#3182ce' }
  }
}

/**
 * 格式化错误消息
 */
export const formatErrorMessage = (error: any): string => {
  if (typeof error === 'string') {
    return error
  }
  
  if (error?.message) {
    return error.message
  }
  
  if (error?.response?.data?.message) {
    return error.response.data.message
  }
  
  return '操作失败，请稍后重试'
}

/**
 * 防抖函数
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void => {
  let timeout: number | null = null
  
  return (...args: Parameters<T>) => {
    if (timeout) {
      clearTimeout(timeout)
    }
    
    timeout = setTimeout(() => {
      func.apply(null, args)
    }, wait)
  }
}

/**
 * 节流函数
 */
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void => {
  let lastTime = 0
  
  return (...args: Parameters<T>) => {
    const now = Date.now()
    
    if (now - lastTime >= wait) {
      lastTime = now
      func.apply(null, args)
    }
  }
}

/**
 * 生成随机字符串
 */
export const generateRandomString = (length: number = 32): string => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''
  
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  
  return result
}

/**
 * 检查是否为移动设备
 */
export const isMobile = (): boolean => {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

/**
 * 获取设备类型
 */
export const getDeviceType = (): 'mobile' | 'tablet' | 'desktop' => {
  const width = window.innerWidth
  
  if (width < 768) {
    return 'mobile'
  } else if (width < 1024) {
    return 'tablet'
  } else {
    return 'desktop'
  }
}
